<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Setting document.domain and IDN</title>
  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
  
</div>

<!--

This testing all gets a bit complicated here; the problem is that our
document.domain implementation will do a suffix comparison of the value to which
it's being set against the current URI's base domain (where "base domain" is
defined as the effective TLD plus one; see nsIEffectiveTLDService.idl).  Seems
simple enough, right?  Wrong.

The problem, as usual, is IDN.  Our current, wholly-inadequate solution to
preventing Unicode domain-name spoofing is done at the level of the URL
implementation, not at the presentation level.  However, the value of the
base domain for the current URI is always calculated in punycode; if the
provided domain is one which is whitelisted, we'll get an IDN name and the
suffix-comparison will fail.  Nice great big mess, huh?

Anyway: "test" currently fits the bill as a TLD which is not whitelisted, while
"δοκιμή" (the Greek IDN TLD for "test") fits the bill as a TLD which is
whitelisted.  RFC 2606 reserves "test" for DNS testing, so nobody's going to
clamor for it to be whitelisted any time soon.  The latter is as of February
2008 undergoing testing for IDN TLDs, and it's at least temporarily whitelisted
for now.  Once the testing period ends the latter's probably going to be
un-whitelisted, so we're going to have to do a careful bit of stepping to ensure
that in the future this test tests what it was intended to test (and, until
bug 414090 is fixed, that it doesn't break when the Greek TLD is
un-whitelisted).

After bug 722299 the IDN whitelist is expected to go away (bug
843689), but bug 414090 still applies, mutatis mutandis. The test has
been changed to use exaмple.test instead (with a Cyrillic м), which
will fail the mixed-script tests and use punycode.
-->

<div>
<h2>Whitelisted</h2>
<iframe name="idnKidWhitelist" src="http://sub1.παράδειγμα.δοκιμή/tests/dom/tests/mochitest/dom-level0/idn_child.html?idn-whitelist"></iframe>
<iframe name="punycodeKidWhitelist" src="http://sub1.παράδειγμα.δοκιμή/tests/dom/tests/mochitest/dom-level0/idn_child.html?punycode-whitelist"></iframe>
</div>

<div>
<h2>Not whitelisted</h2>
<iframe name="idnKidNoWhitelist" src="http://sub1.exaмple.test/tests/dom/tests/mochitest/dom-level0/idn_child.html?idn-nowhitelist"></iframe>
<iframe name="punycodeKidNoWhitelist" src="http://sub1.exaмple.test/tests/dom/tests/mochitest/dom-level0/idn_child.html?punycode-nowhitelist"></iframe>
</div>

<pre id="test">
<script class="testbody" type="application/javascript">

SimpleTest.waitForExplicitFinish();

var gotIDNNoWhitelist = false;
var gotPunycodeNoWhitelist = false;
var gotIDNWhitelist = false;
var gotPunycodeWhitelist = false;

var whitelistRegex =
  new RegExp("^http://sub1\\.παράδειγμα\\.δοκιμή/tests/dom/tests/" +
             "mochitest/dom-level0/idn_child\\.html\\?(.+)$");

var noWhitelistRegex =
  new RegExp("^http://sub1\\.exaмple\\.test/tests/dom/tests/" +
             "mochitest/dom-level0/idn_child\\.html\\?(.+)$");

var state = 0;

var messages =
  [
   "idn-whitelist",
   "punycode-whitelist",
   "idn-nowhitelist",
   "punycode-nowhitelist",
  ];


function receiveMessage(evt)
{
  var origin = evt.origin;
  var match;
  if (/test$/.test(origin))
  {
    // XXX bug 414090
    // The value of MessageEvent.origin with postMessage *should* always be IDN;
    // unfortunately, given our current setup for dealing with Unicode-based
    // domain-name spoofing, whether a domain is in the safe-for-IDN whitelist
    // affects the value of this property (likewise for window.location,
    // document.location, document.domain, and probably a slew of other
    // things).  :-(
    //
    // These two tests should illustrate what currently happens and what should
    // happen once bug 414090 is fixed.
    todo_is(evt.origin, "http://sub1.exaмple.test", "wrong sender");
    todo_isnot(evt.origin, "http://sub1.xn--exaple-kqf.test", "wrong sender");
  }
  else
  {
    // We're receiving data from the Greek IDN name; since that TLD is
    // whitelisted for now, the domain we get isn't going to be punycoded.
    is(evt.origin, "http://sub1.παράδειγμα.δοκιμή", "wrong sender");
  }

  is(messages[state] + "-response", evt.data.split(" ")[0],
     "unexpected data: " + evt.data);

  switch (messages[state])
  {
    case "idn-whitelist":
      gotIDNWhitelist = true;
      ok(evt.source === window.frames.idnKidWhitelist, "wrong source");
      is(evt.data, "idn-whitelist-response", "wrong response for IDN");
      break;

    case "punycode-whitelist":
      gotPunycodeWhitelist = true;
      ok(evt.source === window.frames.punycodeKidWhitelist, "wrong source");
      is(evt.data, "punycode-whitelist-response", "wrong response for punycode");
      break;

    case "idn-nowhitelist":
      gotIDNNoWhitelist = true;
      ok(evt.source === window.frames.idnKidNoWhitelist, "wrong source");
      is(evt.data, "idn-nowhitelist-response", "wrong response for IDN");
      break;

    case "punycode-nowhitelist":
      gotPunycodeNoWhitelist = true;
      ok(evt.source === window.frames.punycodeKidNoWhitelist, "wrong source");
      is(evt.data, "punycode-nowhitelist-response", "wrong response for punycode");
      break;

    default:
      ok(false, "unreached");
      break;
  }

  state++;
}

function run()
{
  var target = window.frames.idnKidWhitelist;
  target.postMessage("idn-whitelist", "http://sub1.παράδειγμα.δοκιμή");

  // Double-timeouts account for 1) delay for message to be received by target
  // window and 2) delay for response from target window to be received by this
  // window.

  setTimeout(function()
  {
    setTimeout(function()
    {
      ok(gotIDNWhitelist, "IDN whitelist message not received");

      var target = window.frames.punycodeKidWhitelist;
      target.postMessage("punycode-whitelist", "http://sub1.παράδειγμα.δοκιμή");

      setTimeout(function()
      {
        setTimeout(function()
        {
          ok(gotPunycodeWhitelist, "punycode whitelist message not received");

          var target = window.frames.idnKidNoWhitelist;
          target.postMessage("idn-nowhitelist", "http://sub1.exaмple.test");

          setTimeout(function()
          {
            setTimeout(function()
            {
              ok(gotIDNNoWhitelist, "IDN no-whitelist message not received");
    
              var target = window.frames.punycodeKidNoWhitelist;
              target.postMessage("punycode-nowhitelist",
                                 "http://sub1.exaмple.test");

              setTimeout(function()
              {
                setTimeout(function()
                {
                  ok(gotPunycodeNoWhitelist,
                     "punycode no-whitelist message not received");

                  SimpleTest.finish();
                }, 0);
              }, 0);
            }, 0);
          }, 0);
        }, 0);
      }, 0);
    }, 0);
  }, 0);
}

window.addEventListener("message", receiveMessage, false);
window.addEventListener("load", run, false);
</script>
</pre>
</body>
</html>
